// package com.mck.interceptor;
//
// import com.fasterxml.jackson.core.type.TypeReference;
// import com.mck.entity.OperationLog;
// import com.mck.entity.RequestRule;
// import com.mck.service.OperationLogService;
// import com.fasterxml.jackson.databind.ObjectMapper;
// import jakarta.servlet.http.HttpServletRequest;
// import jakarta.servlet.http.HttpServletResponse;
// import lombok.NonNull;
// import lombok.extern.slf4j.Slf4j;
// import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.http.HttpMethod;
// import org.springframework.stereotype.Component;
// import org.springframework.util.AntPathMatcher;
// import org.springframework.web.servlet.HandlerInterceptor;
// import org.springframework.web.util.ContentCachingRequestWrapper;
//
// import java.io.IOException;
// import java.time.LocalDateTime;
// import java.util.Arrays;
// import java.util.HashMap;
// import java.util.List;
// import java.util.Map;
//
// @Component
// @Slf4j
// public class OperationLogInterceptor implements HandlerInterceptor {
//
//     @Autowired
//     private OperationLogService operationLogService;
//
//     @Autowired
//     private ObjectMapper objectMapper;
//
//     @Autowired
//     private TokenInterceptor tokenInterceptor;
//
//     // 规则
//     private static final List<RequestRule> INCLUDE_RULES = Arrays.asList(
//             // POST 规则：拆分为独立路径模式
//             new RequestRule("POST", "/api/users"),
//             new RequestRule("POST", "/api/users/list"),
//             new RequestRule("POST", "/api/file"),
//             new RequestRule("POST", "/api/education/classname"),
//             new RequestRule("POST", "/api/education/classname/list"),
//             new RequestRule("POST", "/api/commonProblem"),
//             new RequestRule("POST", "/api/login"),
//             new RequestRule("POST", "/api/system/notice"),
//             new RequestRule("POST", "/api/system/page/add"),
//
//             // PUT 规则：限制到具体资源操作
//             new RequestRule("PUT", "/api/**"),
//
//             // DELETE 规则：精确匹配删除操作
//             new RequestRule("DELETE", "/api/**")
//     );
//
//     // 路径匹配器
//     private final AntPathMatcher pathMatcher = new AntPathMatcher();
//
//     /**
//      * 请求预处理拦截方法
//      * @param request HTTP请求对象
//      * @param response HTTP响应对象
//      * @param handler 目标处理器
//      * @return 始终返回true放行请求
//      */
//     @Override
//     public boolean preHandle(HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) throws Exception {
//
//         // 放行 OPTIONS 预检请求
//         if (HttpMethod.OPTIONS.matches(request.getMethod())) {
//             return true;
//         }
//
//         // 判断是否满足记录规则
//         if (!shouldLog(request)) {
//             return true; // 不满足规则不记录
//         }
//
//         // 获取当前登录用户ID
//         Integer userId = getCurrentUserId(request);
//         log.info("当前登录用户ID: {}", userId);
//         if (userId == null) {
//             return true; // 未登录用户不记录
//         }
//
//         // 构建操作日志对象
//         OperationLog operationLog = new OperationLog();
//         operationLog.setUserId(userId);                    // 操作用户
//         operationLog.setRequestMethod(request.getMethod());// HTTP方法
//         operationLog.setRequestUrl(request.getRequestURI());// 请求路径
//         operationLog.setRequestParams(response.getRequestParams()); // 请求参数（JSON格式）
//         operationLog.setIpAddress(getIpAddress(request)); // 客户端IP（支持代理场景）
//         operationLog.setCreateTime(LocalDateTime.now());   // 操作时间
//
//         operationLogService.saveOperationLog(operationLog); // 持久化日志
//         return true;
//     }
//
//     // 过滤方法
//     private boolean shouldLog(HttpServletRequest request) {
//         String currentMethod = request.getMethod();
//         String currentPath = request.getRequestURI();
//
//         return INCLUDE_RULES.stream().anyMatch(rule -> {
//             boolean methodMatch = rule.getMethod().equalsIgnoreCase(currentMethod);
//             boolean pathMatch = pathMatcher.match(rule.getPath(), currentPath);
//
//             return methodMatch && pathMatch;
//         });
//     }
//
//     // 获取当前登录用户ID
//     private Integer getCurrentUserId(HttpServletRequest request) {
//         // 从token中提取
//         String authHeader = request.getHeader("Authorization");
//         // log.info("Authorization: {}", authHeader);
//         // String token = authHeader.replace("Bearer ", "").trim(); // 去除Bearer前缀
//         // log.info("token: {}", token);
//
//         return tokenInterceptor.getUserIdFromToken(authHeader);
//     }
//
//     /**
//      * 获取客户端真实IP地址
//      */
//     private String getIpAddress(HttpServletRequest request) {
//         String ip = null;
//         // 检查多级代理的X-Forwarded-For，取第一个有效IP
//         String[] headers = {"X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};
//         for (String header : headers) {
//             ip = request.getHeader(header);
//             if (isValidIp(ip)) {
//                 // 处理多级代理的情况（取第一个非unknown的IP）
//                 int index = ip.indexOf(',');
//                 if (index != -1) {
//                     ip = ip.substring(0, index).trim();
//                 }
//                 break;
//             }
//         }
//         // 直接获取远程地址
//         if (!isValidIp(ip)) {
//             ip = request.getRemoteAddr();
//         }
//         // 规范化IPv6本地地址
//         if ("0:0:0:0:0:0:0:1".equals(ip) || "::1".equals(ip)) {
//             ip = "127.0.0.1";
//         }
//         return ip;
//     }
//     private boolean isValidIp(String ip) {
//         return ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip);
//     }
//
//     /**
//      * 获取请求参数（兼容URL参数和Body）
//      */
//     public Map<String, Object> getRequestParams(HttpServletRequest request) {
//         Map<String, Object> params = new HashMap<>();
//
//         // 1. 优先获取URL参数（包括form-data/x-www-form-urlencoded）
//         Map<String, String[]> parameterMap = request.getParameterMap();
//         if (!parameterMap.isEmpty()) {
//             parameterMap.forEach((key, values) -> {
//                 if (values.length == 1) {
//                     params.put(key, values[0]);
//                 } else {
//                     params.put(key, values);
//                 }
//             });
//         }
//
//         // 2. 处理JSON Body（需确保是JSON请求）
//         String contentType = request.getContentType();
//         if (contentType != null && contentType.toLowerCase().contains("application/json")) {
//             try {
//                 // 使用 ContentCachingRequestWrapper 避免流被消费
//                 if (request instanceof ContentCachingRequestWrapper wrapper) {
//                     byte[] body = wrapper.getContentAsByteArray();
//                     if (body.length > 0) {
//                         Map<String, Object> jsonBody = objectMapper.readValue(body, new TypeReference<>() {
//                         });
//                         params.putAll(jsonBody);
//                     }
//                 }
//             } catch (IOException e) {
//                 // 解析失败时忽略JSON Body
//             }
//         }
//
//         return params;
//     }
//
//     /**
//      * 将参数转为JSON字符串（兼容空值）
//      */
//     public String toJsonString(Map<String, Object> params) {
//         try {
//             return objectMapper.writeValueAsString(params);
//         } catch (Exception e) {
//             return "{}";
//         }
//     }
// }